package com.eu.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import com.eu.ebpm.engine.deploy.XmlDefine;
import com.eu.ebpm.engine.entity.args.Param;
import com.eu.ebpm.engine.entity.args.StartupParam;
import com.eu.ebpm.engine.entity.deploy.Transfer;
import com.eu.ebpm.engine.entity.history.HisTask;
import com.eu.ebpm.engine.init.EbpmCache;
import com.eu.ebpm.engine.init.EbpmInitialization;
import com.eu.ebpm.engine.repository.HisExecutionRepository;
import com.eu.ebpm.engine.repository.HisTaskRepository;
import com.eu.ebpm.engine.service.DeployService;
import com.eu.ebpm.engine.service.ExecutionService;
import com.eu.ebpm.engine.service.Task;
import com.eu.ebpm.engine.service.TaskService;

/**
 * 文件上传服务端处理
 *
 */
@Controller
@RequestMapping("/wf")
public class WfUploadController {

	private static final String LOGIN_USER = "LOGIN_USER";

	@Autowired
	private DeployService deployService;

	@Autowired
	private ExecutionService executionService;

	@Autowired
	private TaskService taskService;

	@Autowired
	private HisTaskRepository hisTaskRepository;

	@Autowired
	private HisExecutionRepository hisExecutionRepository;

	@Autowired
	private EbpmInitialization ebpmInitialization;

	@RequestMapping("/index")
	public String index(ModelMap map, HttpSession session) {

		// 用户信息
		map.put("users", User.usersCache.values());
		
		if (this.getUser(session) != null) {
			// 流程部署信息
			map.put("deploys", EbpmCache.getRootDeploys());
			// 待办任务
			map.put("tasks", taskService.createQuery().queryByAssignee(getUsername(session)).list());
			// 待签收列表
			map.put("claimTasks", taskService.createQuery().queryByRoler(getRole(session)).list());
			// 流程管理
			map.put("executions", hisExecutionRepository.list(Param.map("user", getUsername(session))));
		}

		return "wf/index";
	}

	@GetMapping("/deploy")
	public String deploy() {
		return "wf/deploy";
	}
	
	@PostMapping(value="/deploy", produces = "text/html;charset=utf-8")
	@ResponseBody
	public String fileupload(HttpServletRequest request, HttpServletResponse response) throws IllegalStateException, IOException {
		String result = "success";
		// 创建一个通用的多部分解析器
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
		// 判断 request
		if (multipartResolver.isMultipart(request)) {
			// 是否有文件上传,即多部分请求
			MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
			// 取得request中的所有文件名
			Iterator<String> iter = multiRequest.getFileNames();
			while (iter.hasNext()) {
				// 取得上传文件
				MultipartFile file = multiRequest.getFile(iter.next());
				if (file != null) {
					// 取得当前上传文件的文件名称
					String fileName = file.getOriginalFilename();
					// 如果名称不为“”,说明该文件存在，否则说明该文件不存在
					if (fileName.trim() != "") {
						result = new String(file.getBytes(), "utf-8");
					}
				}
			}

		}

		deployService.deploy(result);
		ebpmInitialization.init();
		return XmlDefine.getDrawItem(result);
	}

	// 启动流程
	@RequestMapping("/start")
	public String start(@RequestParam("key") String key, HttpSession session) {
		deployService.activateProcessDefinition(key);
		executionService.startProcessInstanceByKey(key, StartupParam.initAssignee(getUsername(session)));
		return "redirect:/wf/index";
	}

	// 牵手任务
	@RequestMapping("/claim")
	public String claim(@RequestParam("taskId") Long taskId, HttpSession session) {
		taskService.sign(taskId, getUsername(session));
		return "redirect:/wf/index";
	}

	// 流程执行详情
	@RequestMapping("/hisTask")
	public String hisTask(@RequestParam("rootExecutionId") String rootExecutionId, @RequestParam(value = "missionId", required = false) Long missionId,
			@RequestParam(value = "taskId", required = false) Long taskId, ModelMap map, HttpSession session) {

		map.put("taskId", taskId);
		map.put("rootExecutionId", rootExecutionId);

		List<HisTask> hisTasks = hisTaskRepository.listHisTask(Param.map("rootExecutionId", rootExecutionId));

		hisTasks.forEach(v -> {
			if (taskId != null && taskId.equals(v.getId())) {
				map.put("currentMissionName", v.getName());
			}
		});

		map.put("hisTasks", hisTasks);

		if (missionId != null) {
			map.put("missionId", missionId);
			map.put("transfers", EbpmCache.getTransferByMissionId(missionId));
		} else {
			map.put("missionId", hisTasks.get(0).getMissionId());
		}

		return "wf/hisTask";

	}

	// 查询下一步执行路线
	@RequestMapping("/queryTransfers")
	@ResponseBody
	public List<Transfer> queryTransfers(@RequestParam("missionId") Long missionId) {
		return EbpmCache.getTransferByMissionId(missionId);
	}

	@RequestMapping(value = "/jsonData")
	@ResponseBody
	public Map<String, Object> jsonData(@RequestParam("missionId") Long missionId, @RequestParam("rootExecutionId") String rootExecutionId) {
		Map<String, Object> map = new HashMap<String, Object>();
		List<HisTask> hisTasks = hisTaskRepository.listHisTask(Param.map("rootExecutionId", rootExecutionId));
		map.put("hisTasks", hisTasks);
		map.put("jsonData", EbpmCache.getMission(missionId).getDeploy().getJsonData());
		return map;
	}

	@RequestMapping("/executeNext")
	public String executeNext(@RequestParam("express") String express, @RequestParam("remark") String remark, @RequestParam("taskId") Long taskId, HttpSession session) {

		Task task = taskService.createQuery().queryById(taskId).singleResult();

		task.setRemark(remark);

		taskService.complete(task.getId(), Param.map(express, express), task.getRemark());

		return "redirect:/wf/index";
	}

	@RequestMapping("/login")
	public String login(HttpServletRequest request) {
		request.getSession().setAttribute(LOGIN_USER, User.usersCache.get(request.getParameter("username")));
		return "redirect:/wf/index";
	}

	@RequestMapping("/loginOut")
	public String loginOut(HttpServletRequest request) {
		request.getSession().invalidate();
		return "redirect:/wf/index";
	}
	
	private String getUsername(HttpSession session) {
		return getUser(session).getName();
	}

	private String getRole(HttpSession session) {
		return getUser(session).getRole();
	}

	private User getUser(HttpSession session) {
		Object obj = session.getAttribute(LOGIN_USER);
		if (obj == null) {
			return null;
		}
		return (User) obj;
	}

}
